package com.example.rxjavaandretrofitdemo;

import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by tangjiangxu on 11/22/17.
 */

public class HttpMethods {
    public static final String BASE_URL = "https://api.douban.com/v2/movie/";

    private static final int DEFAULT_TIMEOUT = 5;
    private Retrofit retrofit;
    private MovieService2 movieService;

    /**
     * 私有构造方法
     */
    private HttpMethods() {
        // 手动创建一个OKHttpClient并设置超时事件
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);

        retrofit = new Retrofit.Builder()
                .client(httpClientBuilder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(BASE_URL)
                .build();

        movieService = retrofit.create(MovieService2.class);
    }

    /**
     * 在访问HttpMethods时，创建单例
     */
    private static class SingletonHolder {
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    /**
     * 获取单例
     * @return
     */
    public static HttpMethods getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 用于获取豆瓣Top250的数据
     * @param subscriber 由调用者传过来的观察者读喜庆
     * @param start 起始位置
     * @param count 获取长度
     */
    public void getTopMovie(Subscriber<MovieEntity> subscriber, int start, int count) {
        movieService.getTopMovie(start, count)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    /**
     * 用于获取豆瓣Top250的数据
     * @param subscriber 由调用者传过来的观察者读喜庆
     * @param start 起始位置
     * @param count 获取长度
     */
    public void getTopMovie2(Subscriber<List<MovieEntity.SubjectsBean>> subscriber, int start, int count) {
        Observable observable = movieService.getTopMovie2(start, count)
                .map(new HttpResultFunc<List<MovieEntity.SubjectsBean>>());
        toSubscribe(observable, subscriber);

    }

    /**
     * 添加线程管理并订阅读
     * @param o
     * @param s
     */
    private void toSubscribe(Observable o, Subscriber s) {
        o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s);
    }

    /**
     * 用来统一处理Http的resultCode，并将HttpResult的Data剥离出来返回给subscriber
     * @param <T> Subscriber真正需要的数据类型，也就是Data部分的数据类型
     */
    private class HttpResultFunc<T> implements Func1<HttpResult<T>, T> {

        @Override
        public T call(HttpResult<T> httpResult) {
            if (httpResult.start != 0) {
                try {
                    throw new ApiException("" + httpResult.start);
                } catch (ApiException e) {
                    e.printStackTrace();
                }
            }
            return httpResult.subjects;
        }
    }
}
